using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;

namespace haxeProject
{
	public class ProjectFiles : System.Windows.Forms.UserControl
	{
		private System.Windows.Forms.MenuItem mNew;
		private System.Windows.Forms.MenuItem mRename;
		private System.Windows.Forms.MenuItem mRemove;
		private System.Windows.Forms.MenuItem mAdd;
		private System.Windows.Forms.ContextMenu fmenu;
		private System.Windows.Forms.MenuItem mFolder;
		private System.Windows.Forms.MenuItem break1;
		private System.Windows.Forms.MenuItem mFile;
		public System.Windows.Forms.TreeView Files;
		private PluginMain plugin;
		private Node droptarget;

		public ProjectFiles( PluginMain plugin )
		{
			InitializeComponent();
			this.plugin = plugin;
			Files.ImageList = Icons.list;
		}

		#region Windows Forms Designer generated code
		private void InitializeComponent() {
			this.Files = new System.Windows.Forms.TreeView();
			this.mFile = new System.Windows.Forms.MenuItem();
			this.break1 = new System.Windows.Forms.MenuItem();
			this.mFolder = new System.Windows.Forms.MenuItem();
			this.fmenu = new System.Windows.Forms.ContextMenu();
			this.mAdd = new System.Windows.Forms.MenuItem();
			this.mRemove = new System.Windows.Forms.MenuItem();
			this.mRename = new System.Windows.Forms.MenuItem();
			this.mNew = new System.Windows.Forms.MenuItem();
			this.SuspendLayout();
			// 
			// Files
			// 
			this.Files.AllowDrop = true;
			this.Files.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
						| System.Windows.Forms.AnchorStyles.Left) 
						| System.Windows.Forms.AnchorStyles.Right)));
			this.Files.ImageIndex = -1;
			this.Files.LabelEdit = true;
			this.Files.Location = new System.Drawing.Point(8, 8);
			this.Files.Name = "Files";
			this.Files.SelectedImageIndex = -1;
			this.Files.Size = new System.Drawing.Size(256, 536);
			this.Files.TabIndex = 0;
			this.Files.KeyDown += new System.Windows.Forms.KeyEventHandler(this.FilesKeyDown);
			this.Files.AfterExpand += new System.Windows.Forms.TreeViewEventHandler(this.FilesAfterExpand);
			this.Files.AfterCollapse += new System.Windows.Forms.TreeViewEventHandler(this.FilesAfterCollapse);
			this.Files.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FilesMouseUp);
			this.Files.DragOver += new System.Windows.Forms.DragEventHandler(this.FilesDragOver);
			this.Files.DoubleClick += new System.EventHandler(this.FilesDoubleClick);
			this.Files.AfterLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.FilesAfterLabelEdit);
			this.Files.DragEnter += new System.Windows.Forms.DragEventHandler(this.FilesDragEnter);
			this.Files.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.FilesItemDrag);
			this.Files.BeforeLabelEdit += new System.Windows.Forms.NodeLabelEditEventHandler(this.FilesBeforeLabelEdit);
			this.Files.DragLeave += new System.EventHandler(this.FilesDragLeave);
			this.Files.DragDrop += new System.Windows.Forms.DragEventHandler(this.FilesDragDrop);
			// 
			// mFile
			// 
			this.mFile.Index = 0;
			this.mFile.Text = "File";
			this.mFile.Click += new System.EventHandler(this.menuCommand);
			// 
			// break1
			// 
			this.break1.Index = 2;
			this.break1.Text = "-";
			// 
			// mFolder
			// 
			this.mFolder.Index = 1;
			this.mFolder.Text = "Folder";
			this.mFolder.Click += new System.EventHandler(this.menuCommand);
			// 
			// fmenu
			// 
			this.fmenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
						this.mNew,
						this.mAdd,
						this.break1,
						this.mRename,
						this.mRemove});
			// 
			// mAdd
			// 
			this.mAdd.Index = 1;
			this.mAdd.Text = "Add...";
			this.mAdd.Click += new System.EventHandler(this.menuCommand);
			// 
			// mRemove
			// 
			this.mRemove.Index = 4;
			this.mRemove.Text = "Remove";
			this.mRemove.Click += new System.EventHandler(this.menuCommand);
			// 
			// mRename
			// 
			this.mRename.Index = 3;
			this.mRename.Text = "Rename";
			this.mRename.Click += new System.EventHandler(this.menuCommand);
			// 
			// mNew
			// 
			this.mNew.Index = 0;
			this.mNew.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
						this.mFile,
						this.mFolder});
			this.mNew.Text = "New...";
			// 
			// ProjectFiles
			// 
			this.AllowDrop = true;
			this.Controls.Add(this.Files);
			this.Name = "ProjectFiles";
			this.Size = new System.Drawing.Size(272, 552);
			this.ResumeLayout(false);
		}
		#endregion
		
		ProjectFile curfile {
			get {
				TreeNode n = Files.SelectedNode;
				if( n == null )
					return null;
				return n.Tag as ProjectFile;
			}
		}
		
		ProjectFile curdir {
			get {
				ProjectFile f = curfile;
				if( f == null )
					return Files.Nodes[0].Tag as ProjectFile; // root
				while( !f.isFolder )
					f = f.parent;
				return f;
			}
		}
		
		public Node Get( ProjectFile f ) {
			return GetRec(f,Files.Nodes[0] as Node);
		}
		
		Node GetRec( ProjectFile f, Node n ) {
			if( n.Tag == f )
				return n;
			foreach( Node c in n.Nodes ) {
				Node found = GetRec(f,c);
				if( found != null )
					return found;
			}
			return null;
		}
		
		void menuCommand(object sender, System.EventArgs e)
		{
			if( sender == mAdd ) {
				ProjectFile target = curdir;
				String basedir = null;
				foreach( ProjectFile c in target.childs ) {
					if( c.isFolder ) continue;
					basedir = System.IO.Path.GetDirectoryName(c.path);
					break;
				}
				string[] files = Dialog.OpenMultiple(Dialog.HX,basedir);
				if( files == null )
					return;
				bool all = true;
				foreach( string file in files )
					if( !plugin.addFile(file,target,false) )
						all = false;
				if( !all )
					Dialog.Message("Some files already in the Project were not added");
				return;
			}
			if( sender == mFile ) {
				ProjectFile target = curdir;
				String basedir = null;
				foreach( ProjectFile c in target.childs ) {
					if( c.isFolder ) continue;
					basedir = System.IO.Path.GetDirectoryName(c.path);
					break;
				}				
				String file = Dialog.Create(Dialog.HX,basedir);
				if( file == null )
					return;
				if( !plugin.addFile(file,target,true) )
					Dialog.Message("The file "+file+" is already in the Project");
				return;
			}
			if( sender == mFolder ) {
				plugin.addDir(curdir);
				return;
			}
			if( sender == mRename) {
				if( curfile.isFolder )
					Files.SelectedNode.BeginEdit();
				return;
			}
			if( sender == mRemove ) {
				if( curfile.isFolder && curfile.childs.Count > 0 && !Dialog.Confirm("Remove '"+curfile.path+"' from Project ?") )
					return;
				plugin.removeFile(curfile);
				return;
			}
		}
		
		void FilesAfterExpand(object sender, System.Windows.Forms.TreeViewEventArgs e)
		{
			(e.Node.Tag as ProjectFile).expanded = true;
		}
		
		void FilesAfterCollapse(object sender, System.Windows.Forms.TreeViewEventArgs e)
		{
			(e.Node.Tag as ProjectFile).expanded = false;
		}
		
		void FilesDoubleClick(object sender, System.EventArgs e)
		{
			Node n = Files.SelectedNode as Node;
			if( n == null )
				return;
			ProjectFile f = n.Tag as ProjectFile;
			if( !f.isFolder )
				plugin.openFile(f);
		}
				
		void FilesMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			if( e.Button == MouseButtons.Right ) {
				Point pt = new Point(e.X,e.Y);
				Files.SelectedNode = Files.GetNodeAt(pt);
				bool ext = (curfile != null && curfile.parent != null);
				mRemove.Enabled = ext;
				mRename.Enabled = ext && curfile.isFolder;
				fmenu.Show(Files,pt);
			}
		}
		
		void FilesAfterLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e) {
			ProjectFile f = e.Node.Tag as ProjectFile;
			f.path = e.Label;
		}
		
		void FilesBeforeLabelEdit(object sender, System.Windows.Forms.NodeLabelEditEventArgs e) {
			if( !(e.Node.Tag as ProjectFile).isFolder )
				e.CancelEdit = true;
		}
		
		void FilesItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
		{
			Files.SelectedNode = null;
			Files.DoDragDrop(e.Item,DragDropEffects.Move);
		}
		
		void FilesDragEnter(object sender, System.Windows.Forms.DragEventArgs e)
		{
			// filter content accepted
			e.Effect = DragDropEffects.Move;			
		}

		void FilesDragOver(object sender, System.Windows.Forms.DragEventArgs e)
		{			
			Node n = Files.GetNodeAt(Files.PointToClient(Control.MousePosition)) as Node;
			if( n == null )
				n = Files.Nodes[0] as Node;
			ProjectFile f = n.Tag as ProjectFile;
			while( !f.isFolder )
				f = f.parent;
			n = Get(f);
			if( droptarget == n )
				return;
			if( droptarget != null )
				droptarget.BackColor = Color.Transparent;
			droptarget = n;
			droptarget.BackColor = Color.BurlyWood;
			e.Effect = DragDropEffects.Move;
		}
		
		void FilesDragDrop(object sender, System.Windows.Forms.DragEventArgs e)
		{
			if( droptarget == null )
				return;
			ProjectFile target = droptarget.Tag as ProjectFile;
			droptarget.BackColor = Color.Transparent;
			droptarget = null;
			
			Node n = e.Data.GetData(typeof(Node)) as Node;
			if( n != null ) {
				plugin.moveFile(n.Tag as ProjectFile,target);
				return;
			}
			
			Array a = e.Data.GetData(DataFormats.FileDrop) as Array;		
			for (int i=0; i<a.Length; i++)				
				plugin.addFile(a.GetValue(i) as string,target,false);
			
		}		
		
		void FilesKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if( e.KeyData == Keys.Delete && curfile != null )
				menuCommand(mRemove,null);
		}
		
		void FilesDragLeave(object sender, System.EventArgs e)
		{
			if( droptarget != null ) {
				droptarget.BackColor = Color.Transparent;
				droptarget = null;
			}
		}
		
	}
}
